import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# show all data when printing
pd.set_option('display.max_rows', None, 'display.max_columns', None, 'display.max_colwidth', 1000, 'display.expand_frame_repr', False)

# load data
df = pd.read_csv(r'../../../../../large_data/共享单车/train.csv')
m = len(df)
# columns:
# datetime  season  holiday  workingday  weather  temp   atemp  humidity  windspeed  casual  registered  count
# atemp 体感温度？
# casual 未注册用户租赁数
# registered 注册用户租赁数
# count = casual + registered

# 将datetime列，切分出年月日时
df['date'] = df.apply(lambda x: x.datetime.split(' ')[0], axis=1)  # ATTENTION apply axis=1
df['Y'] = df.date.map(lambda x: int(x.split('-')[0], 10))
df['M'] = df.date.map(lambda x: int(x.split('-')[1], 10))
df['D'] = df.date.map(lambda x: int(x.split('-')[2], 10))
df['H'] = df.datetime.map(lambda x: int(x.split(' ')[1].split(':')[0], 10))

# figure group 1
plt.figure(figsize=[16, 8])
spr = 2
spc = 3
spn = 0

# 按照小时，统计用车数量
spn += 1
plt.subplot(spr, spc, spn)
# bar
# line: 折线图
# kde: 密度图
h_cnt = df.groupby('H')['count'].sum().plot(kind='bar')


# 最终按照上班高峰，下班高峰，白天低谷，晚上低谷，分成四个小时段
def h_section(h):
    if h <= 6:
        return 1
    elif h <=10:
        return 2
    elif h <=15:
        return 3
    elif h <=19:
        return 4
    else:
        return 5


df['h_section'] = df['H'].apply(h_section)

# 将cnt中的噪音值用箱线图进行显示
spn += 1
plt.subplot(spr, spc, spn)
sns.boxplot(data=df, y='count')

# 显示非噪音数据的比例
mu = df['count'].mean()
sigma = df['count'].std()
idx_bad = abs(df['count'] - mu) >= 3 * sigma
idx_good = np.invert(idx_bad)
print(f'非噪音数据的比例: {1 - sum(idx_bad)/len(idx_bad)}')
noise_df = df[idx_bad]
good_df = df[idx_good]

# 删除噪音数据（保留非噪音数据）
df = good_df

# 绘制所有连续特征的热图   将连续值中关系大于0.6的数据删除一项
# temp,atemp,humidity,windspeed,casual,registered,count
x_orig = df[['temp', 'atemp', 'humidity', 'windspeed', 'casual', 'registered', 'count']]
x = x_orig.copy()
xcorr = x.corr()
print(xcorr)
spn += 1
plt.subplot(spr, spc, spn)
sns.heatmap(xcorr, annot=True)

xone = False
x_rm_list = set()
for i, idx in enumerate(xcorr.index):
    # if xone:
    #     break
    for j, col in enumerate(xcorr.iloc[i].index):
        # if xone:
        #     break
        if j <= i:
            continue
        val = xcorr.iloc[i, j]
        if float(val) > 0.6:
            x_rm_list.add(x.columns[j])
            xone = True
for col in x_rm_list:
    del x[col]
print(x[:5])
del x_orig['atemp']
del x_orig['casual']
del x_orig['registered']
print(x_orig[:5])

# 绘制假日和非假日不同小时用车辆
wd_h = df.groupby(['workingday', 'H'])['count'].sum().reset_index()
spn += 1
plt.subplot(spr, spc, spn)
sns.pointplot(data=wd_h, x='H', y='count', hue='workingday')

# 绘制不同季节不同小时的用车辆
s_h = df.groupby(['season', 'H'])['count'].sum().reset_index()
spn += 1
plt.subplot(spr, spc, spn)
sns.pointplot(data=s_h, x='H', y='count', hue='season')

# 将数据切分为训练集和测试集
from sklearn.model_selection import train_test_split
x_orig_train, x_orig_test = train_test_split(x_orig, train_size=0.7, random_state=666)
x_train = x_orig_train.iloc[:, :-1]
x_test = x_orig_test.iloc[:, :-1]
y_train = x_orig_train.iloc[:, -1]
y_test = x_orig_test.iloc[:, -1]
print(x_train[:5])
print(y_train[:5])

# 分别使用L1正则和L2正则处理模型
from sklearn.linear_model import Ridge, Lasso
l1 = Lasso()
l2 = Ridge()
params = dict(alpha=[0.1, 0.2, 0.3, 0.4, 0.7, 0.9])

# 找到最优模型和最优得分
from sklearn.model_selection import GridSearchCV
grid01 = GridSearchCV(l1, params, cv=5)
grid01.fit(x_train, y_train)
print(grid01.best_params_, grid01.best_score_)
grid02 = GridSearchCV(l2, params, cv=5)
grid02.fit(x_train, y_train)
print(grid02.best_params_, grid02.best_score_)


# show all drawings
plt.show()
